Skip to content

Add opt-in borrowed receive storage for compact BF16 dispatch - #769

Open
yuweih205 wants to merge 1 commit into
deepseek-ai:mainfrom
yuweih205:perf/borrowed-recv-view
Open

yuweih205 wants to merge 1 commit into
deepseek-ai:mainfrom
yuweih205:perf/borrowed-recv-view

Conversation

@yuweih205

@yuweih205 yuweih205 commented Sep 30, 2026 •

Copy link
Copy Markdown

dispatch(..., borrow_recv=True) skips the activation copy of the dispatch epilogue: the epilogue writes only metadata plus a row map and returns a DispatchRecvView (slab, row_indices) over the communication buffer, which an indexed consumer such as a gathered GEMM reads directly. The view holds an exclusive lease: release(*streams) orders the next communication after the consumers, and dispatch/combine/LB calls/destroy() reject an active view. Supported: fresh compact BF16 dispatch within one NVLink domain with CPU counts and defer_epilogue=False; everything else is rejected up front. Default behavior is unchanged.

8×H200, deterministic, hidden 3072, top-8, 16 local experts, dispatch plus the same indexed consumer: −13.1% at 8192 tokens/rank and −13.5% at 16384, but +15.9% at 1024, hence opt-in. Fixed-route serial forward only; no overlap or training-throughput claim. Combined with DeepGEMM #463 in a live EP8 + gate/up GEMM + SwiGLU step: −17%. Raw cycles and the reproducer: gist.

Test: python tests/ep/test_recv_view.py --num-processes 8 (bitwise payload/metadata against the gathered inputs, replay/combine after release, delayed cross-stream readers, invalid-mode rejection).

Re-validated 2026-10-16 at 71157be (native code byte-identical to the measured build) on 8×H200, PyTorch 2.13.0+cu132: test_recv_view.py 16/16 cases under both EP_AVOID_RECORD_STREAM policies; the EP8 functional suite passes with CPU counts for direct and deferred epilogues. With --do-cpu-sync 0 the unmodified suite stops at its full-capacity recv_x_twice comparison on this branch exactly as on upstream main; with the valid-prefix comparison from #786 it passes on both.

@yuweih205

Copy link
Copy Markdown
Author

Follow-up validation at 9e8f58203a0b3941efb7e9fb6aca43e75ecb01ac:

  • Added regression checks for access/release before the asynchronous event wait, access/double release after release, and rejection of an FP8 tensor/scale tuple. This commit adds 12 test lines only; production code is unchanged.
  • Added native deferred materialization as a third benchmark arm, with the same indexed dual-GEMM/SwiGLU consumer and serial-forward contract. The deferred arm calls current_stream_wait() exactly once, immediately after dispatch.

Eight H200 GPUs in one NVLink domain; deterministic compact BF16; exact CPU receive counts; D=3072, F=1280, top-8, 16 local experts and 16 communication SMs. All three arms use the same candidate build. Three fresh processes, each with 12 blocks covering all six arm orders twice, 20 calls/arm/block and 20 warmup calls/arm. The metric is synchronized wall time through device completion, including CPU orchestration, dispatch, consumer and release: median across 36 maximum-rank block means per arm/shape.

Tokens/rank Ordinary materialized (ms) Native deferred (ms) Borrowed (ms) Borrowed time reduction vs ordinary vs deferred
1024 0.546836 0.540047 0.614259 -12.33% -13.74%
8192 3.029620 3.030416 2.631033 13.16% 13.18%
16384 5.903495 5.913038 5.103534 13.55% 13.69%

All three fresh-process median comparisons improve at 8192/16384 and regress at 1024, including versus deferred. This remains opt-in; the small-token regression is not hidden. These are one-node component timings, not full-training or overlapped-batch throughput. Fixed routing-plan construction, final expert projection, combine, backward and optimizer are outside the measurement. The exclusive same-buffer lease and forward-only lifetime restrictions are unchanged.

Validation passed 256 distributed lease rank/cases (16 combinations × 8 ranks × both EP_AVOID_RECORD_STREAM=0/1 policies) and 216 dispatch rank/cases across arms/shapes/processes. Payload, IDs, weights and both source-metadata columns match an independent input/route oracle bitwise; the shared consumer outputs match bitwise before and after timing. Input/weight fingerprints, all 324 timing records, eight-rank reductions and completion markers were audited independently.

Provenance: Torch 2.13.0+cu132, CUDA 13.2, actually loaded NCCL 2.32.3. This reuses the existing validated native extension from 59abc161bb70509994375e96e3efa6b0e0748e36, whose production implementation is equivalent to the current PR (later differences are comments/docstrings/tests); it is not a newly compiled head extension. Native SHA256: def1af547d483ad52edb145c8cc31a948738e6326ca598226149f142dc2f8b88.

New report, exact protocol, CPU-only audit and GPU reproduction instructions. The gist contains the new benchmark/analyzer, raw per-rank logs, frozen manifest and analysis; all historical evidence is retained. This does not revise the distinct combined DeepGEMM measurements or the separate prefix-sort prototype results.

@yuweih205
yuweih205 force-pushed the perf/borrowed-recv-view branch from 9e8f582 to 71157be Compare October 16, 2026 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant